(function(){
	'use strict';
	/**
	 *	zhx.Loading
	 *
	 *  Author : Vicco Wang
	 *  Date : 2016.11.17
	 *
	 *  url : http://git.oschina.net/vicco/zhx-loading
	 *
	 *  dependecy:
	 *  [Angular]
	 *  [Velocity]
	 *
	 *  useage:
	 *
	 *  1. 引入JS与CSS文件;
	 *  2. 依赖注入 zhxLoadingModule 模块;
	 *  3. 控制器或指令中使用以下方法来创建一个LOADING,该方法会返回loading作用域;
	 *  
	 *  var loading = zhxLoadingService.createLoading({
	 *  	target : 'someDomId'
	 *  });
	 *
	 *  //use scope method to close loading
	 *  loading.close();
	 *
	 *  createLoading方法中可以传递如下配置参数
	 *
	 *  target 		{ dom Id }	指定Loading加载遮罩哪个元素，如果不设置默认为整个页面遮罩
	 *  type   		{ number } 	指定Loading的动画样式，暂未支持
	 *  animate 	{ boolean } 是否使用动画来展示
	 *  opacity		{ floatNum} 小数，表示遮罩透明度
	 *  text 		{ string }	Loading中间的提示文字，如果设置了该参数，则显示文字，否则按照默认显示图示
	 *
	 */
	var LD = angular.module('zhxLoadingModule',[]);

	LD.factory('zhxLoadingService', ['$rootScope','$compile','$templateCache','$timeout',function($rootScope,$compile,$templateCache,$timeout){

		var service = {};

		service.createLoading = function( options ){

			//normal options
			var loadingOpts = {
				target : null,		//#id
				type : 1,			//animation type
				animate : true,		//show animate
				opacity : .6,
				text : null			//display some text in loading block
			};

			//extend users options
			var opts = angular.extend({}, loadingOpts, options );

			var loadingScp = $rootScope.$new(true),
				target = opts.target ? angular.element('#' + opts.target) : angular.element('body'),
				targW = target.outerWidth(),
				loadingPicSize = targW / 3000,
				targetPos = target.css('position');

			//init loading scope
			loadingScp = angular.extend(loadingScp,{
				_target : target,
				_targetPos : targetPos,
				_initalPos : targW > 1000 ? targW / 2 : targW / 4,
				_loadingPicSize : loadingPicSize > 0.3 ? loadingPicSize : 0.3,
				_loadingPic : null,
				type : 1,
				animate : opts.animate,
				opacity : opts.opacity,
				text : opts.text,
				close : function(){}
			});

			//如果已存在LOADING，则不再创建，返回一个初始化的LOADING SCOPE
			if( target && target.hasClass('zhx-loading-created') ) return loadingScp;

			//init loading pic
			var loadingPic = [];
			for( var i = 0; i < 13; i++){
				loadingPic.push(i);
			}
			loadingScp._loadingPic = loadingPic;

			//外部可调用
			loadingScp.close = function(){

				var __removeLoading = function(dom){
					angular.element(dom).remove();
					target.removeClass('zhx-loading-created zhx-loading-overflow zhx-loading-relative');
					loadingScp.$destroy();
				}

				if( opts.animate ){
					loadingTemplate.velocity({
						opacity : 0
					},{
						duration : 300,
						complete : function(dom){
							__removeLoading(dom)
						}
					})
				} else {
					__removeLoading(loadingTemplate);
				}
				
			};

			target.addClass('zhx-loading-created zhx-loading-overflow');

			if( targetPos === 'static' ) target.addClass('zhx-loading-relative');

			var loadingTemplate = $compile( $templateCache.get('zhx.loading.tpl.vicco') )(loadingScp);

			if( !opts.target || opts.target === 'body' || opts.target === null ) {
				loadingScp.animate = false;
				loadingTemplate.css('position','fixed');
			}

			loadingTemplate.css('backgroundColor', 'rgba(0,0,0,' + opts.opacity + ')' );

			loadingTemplate.appendTo( target );

			if( loadingScp.animate ){
				$timeout(function(){
					loadingTemplate.velocity({
						scale : '500%',
						opacity : 1
					},{
						duration : 240
					});
				},20)
			} else {
				loadingTemplate.css({
					transform :'scale(5)',
					opacity :1
				})
			}

			return loadingScp;

		};

		return service;

	}]);

	LD.run(['$templateCache',function($templateCache){
		//zhx.loading.template
		$templateCache.put('zhx.loading.tpl.vicco',
			'<div id="zhx-loading-wrapper" ng-style="::{ width: _initalPos, height: _initalPos }">' +
				'<div class="sk-circle" ng-if="!text" style="transform: scale({{ ::_loadingPicSize }} )">' +
				  '<div class="sk-circle{{$index}} sk-child" ng-repeat="pic in ::_loadingPic"></div>' +
				'</div>' +
				'<div class="zhx-loading-text" ng-if="text" ng-bind="::text"></div>' +
			'</div>');

	}]);

})()